#include <gtest/gtest.h>

using namespace std;

class Parent
{
public:
    virtual string GetVirtualName() {
        return "Parent";
    }
    string GetName() {
        return "Parent";
    }
};

class Child : public Parent
{
public:
    virtual string GetVirtualName() {
        return "Child";
    }
    string GetName() {
        return "Child";
    }
};

static string CallParentName(Parent p){
    return p.GetName();
};

static string CallRefParentName(Parent& p){
    return p.GetName();
};

static string CallPointerParentName(Parent* p){
    return p->GetName();
};

static string CallParentVirtualName(Parent p){
    return p.GetVirtualName();
};

static string CallRefParentVirtualName(Parent& p){
    return p.GetVirtualName();
};

static string CallPointerParentVirtualName(Parent* p){
    return p->GetVirtualName();
};

TEST(INHERITAGE, INSTANCE_PARAM)
{
    Child c;
    Parent p;
    // 1. 不能将父类对象或指针传递给子类参数
    // 2. 调用非虚函数时，是根据对象定义获取函数位置，故不会调用子类的方法
    EXPECT_EQ(CallParentName(c), "Parent");
    EXPECT_EQ(CallRefParentName(c), "Parent");
    EXPECT_EQ(CallPointerParentName(&c), "Parent");

    // 3. 传递实参时，会创建父类对象，并将子类的成员复制给父类，调用的还是父类的方法
    EXPECT_EQ(CallParentVirtualName(c), "Parent");

    // 4. 仅在传递引用或指针时，调用虚函数时可能调用子类的函数
    EXPECT_EQ(CallRefParentVirtualName(c), "Child");
    EXPECT_EQ(CallPointerParentVirtualName(&c), "Child");
}